//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __GMODULE_H__
#define __GMODULE_H__

#include "csection.h"
#include <linknode.h>
#include <interlocked.h>

typedef enum ModuleTachStatus {
    ModuleTachStatus_INIT,
    ModuleTachStatus_ATTACHED,
    ModuleTachStatus_DETACHED,
} ModuleTachStatus;


typedef enum ModuleFileType {
    ModuleFileType_EXE  = 0,
    ModuleFileType_DLL  = 0x2000, // equal to IMAGE_FILE_DLL (in peimage.h)
    ModuleFileType_MARK = 0x2000
} ModuleFileType;

class GModule : public DLinkNode {
public:
    Aura_UInt32 AddRef(void);
    Aura_UInt32 Release(void);
         
    GModule();
    ~GModule();
    Aura_Bool AllocMemery(Aura_UInt32 uImageBase, Aura_UInt32 uTotalSize);
    Aura_Bool AttachProcess(Aura_PVoid preserved);
    Aura_Bool DetachProcess(Aura_PVoid preserved);
    
public:
    Aura_PWChar       m_wszName;
    Aura_PWChar       m_wszFullPath;

    Aura_UInt32       m_uImageBase;
    Aura_UInt32       m_uTotalSize;
    Aura_UInt32       m_uRelocOffset;
    Aura_UInt32       m_uEntryPoint;
    
    Aura_UInt32       m_cSections;
    Section *         m_pSections;

    Section *         m_pExport;
    Aura_UInt32       m_uExportOffset;
    Aura_UInt32       m_uExportSize;

    Section *         m_pImport;
    Aura_UInt32       m_uImportOffset;
    Aura_UInt32       m_uImportSize;

    Section *         m_pResource;

    DLinkNode         m_rModuleList;
    DLinkNode         m_win32ModuleList;
    
    ModuleFileType    m_fileType;
    ModuleTachStatus  m_attached; 

public:
    Interlocked     m_cRef;     
};


inline GModule::GModule() :
    m_wszName(AURA_NULL),
    m_wszFullPath(AURA_NULL),
    m_uImageBase(0),
    m_pSections(AURA_NULL),
    m_pExport(AURA_NULL),
    m_pImport(AURA_NULL),
    m_pResource(AURA_NULL),
    m_attached(ModuleTachStatus_INIT)
{
    Initialize();
    m_rModuleList.Initialize();
    m_win32ModuleList.Initialize();
}


struct ModuleRef : public DLinkNode {
    GModule     *m_pModule;
    ModuleRef(GModule *pModule) : m_pModule(pModule) { }
};

struct Win32ModuleRef : public DLinkNode {
	Aura_PVoid     m_pWin32Module;
	Win32ModuleRef(Aura_PVoid pWin32Module) : m_pWin32Module(pWin32Module) { }
};


EXTERN_C Aura_Bool ProcessAttach(GModule *pModule, Aura_PVoid preserved);
EXTERN_C void ProcessDetach(DLinkNode *pModuleList, Aura_PVoid preserved);

#endif  //__GMODULE_H__
